package com.twq.conversionsparam

import java.util.concurrent.{Callable, Executors}

/**
 * Created by tangweiqun on 2017/11/18.
 */
trait ThreadStrategy {
  def execute[A](op: () => A): () => A
}

object SameThreadStrategy extends ThreadStrategy {
  override def execute[A](op: () => A): () => A = op
}

object ThreadPoolStrategy extends ThreadStrategy {
  val pool = Executors.newFixedThreadPool(Runtime.getRuntime.availableProcessors())

  Runtime.getRuntime.addShutdownHook(new Thread() {
    override def run(): Unit = pool.shutdown()
  })

  override def execute[A](op: () => A): () => A = {

    val future = pool.submit(new Callable[A] {
      override def call(): A = {
        println("Executing function on thread:" + Thread.currentThread())
        op()
      }
    })
    () => future.get()
  }
}

object Utils {
  def compute(value: Int)
             (implicit threading: ThreadStrategy = SameThreadStrategy): Unit = {
    (0 to value).map(i => threading.execute(() => println(i))).foreach(_ ())
  }
}

object ImplicitDefaultParam {
  def main(args: Array[String]): Unit = {
    implicit val th = ThreadPoolStrategy
    Utils.compute(100)
  }
}


